﻿/*
	wp8libflac project
	© Alovchin, 2014
*/

using System.Collections.Generic;
using System.Linq;
using Windows.ApplicationModel.Background;
using Windows.Foundation.Collections;
using Windows.Media;
using Windows.Media.Playback;
using wp81cs.Streaming;

namespace wp81cs.BackgroundAudio
{
    public sealed class BackgroundAudioTask : IBackgroundTask
    {
        private BackgroundTaskDeferral _taskDeferral;
        private SystemMediaTransportControls _mediaTransportControls;
        private readonly List<string> _trackList;
        private MediaSourceAdapter _mediaSourceAdapter;

        public BackgroundAudioTask()
        {
            this._trackList = new List<string>();
        }

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            this._mediaTransportControls = SystemMediaTransportControls.GetForCurrentView();

            this._mediaTransportControls.ButtonPressed += this.OnMediaTransportControlsButtonPressed;
            this._mediaTransportControls.IsEnabled = true;
            this._mediaTransportControls.IsPlayEnabled = true;
            this._mediaTransportControls.IsPauseEnabled = true;
            this._mediaTransportControls.DisplayUpdater.ClearAll();
            this._mediaTransportControls.DisplayUpdater.Type = MediaPlaybackType.Music;
            this._mediaTransportControls.DisplayUpdater.Update();
            
            taskInstance.Canceled += this.OnTaskCanceled;
            taskInstance.Task.Completed += this.OnTaskCompleted;

            BackgroundMediaPlayer.Current.AutoPlay = true;
            BackgroundMediaPlayer.Current.CurrentStateChanged += this.OnCurrentStateChanged;
            BackgroundMediaPlayer.MessageReceivedFromForeground += this.OnMessageReceivedFromForeground;

            BackgroundMediaPlayer.SendMessageToForeground(new ValueSet {{"BackgroundPlayerStarted", null}});

            this._taskDeferral = taskInstance.GetDeferral();
        }

        private void OnMessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e)
        {
            foreach (var data in e.Data.Where(d => d.Value is string))
            {
                if (data.Key.Equals("AddTrack"))
                {
                    this._trackList.Add(data.Value as string);
                }
            }

            if (!this._trackList.Any())
            {
                return;
            }

            var currentState = BackgroundMediaPlayer.Current.CurrentState;
            if (currentState == MediaPlayerState.Closed || currentState == MediaPlayerState.Stopped)
            {
                var firstTrack = this._trackList.First();
                this._mediaSourceAdapter = MediaSourceFactory.Create(firstTrack);
                BackgroundMediaPlayer.Current.SetMediaSource(this._mediaSourceAdapter.MediaSource);
            }
        }

        private void OnCurrentStateChanged(MediaPlayer sender, object args)
        {
            switch (sender.CurrentState)
            {
                case MediaPlayerState.Playing:
                    this._mediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Playing;
                    break;
                case MediaPlayerState.Paused:
                    this._mediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Paused;
                    break;
                case MediaPlayerState.Stopped:
                    this._mediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Stopped;
                    break;
                case MediaPlayerState.Closed:
                    this._mediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Closed;
                    break;
            }
        }

        private void OnMediaTransportControlsButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs e)
        {
            switch (e.Button)
            {
                case SystemMediaTransportControlsButton.Play:
                    BackgroundMediaPlayer.Current.Play();
                    break;
                case SystemMediaTransportControlsButton.Pause:
                    BackgroundMediaPlayer.Current.Pause();
                    break;
            }
        }

        private void OnTaskCompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs e)
        {
            this._taskDeferral.Complete();
        }

        private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            this._mediaTransportControls.ButtonPressed -= this.OnMediaTransportControlsButtonPressed;

            sender.Canceled -= this.OnTaskCanceled;
            sender.Task.Completed -= this.OnTaskCompleted;

            BackgroundMediaPlayer.Current.CurrentStateChanged -= this.OnCurrentStateChanged;
            BackgroundMediaPlayer.MessageReceivedFromForeground -= this.OnMessageReceivedFromForeground;

            BackgroundMediaPlayer.Shutdown();

            this._taskDeferral.Complete();
        }
    }
}
